#include <jni.h>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <android/log.h>
#include "polarsslh/entropy.h"
#include "polarsslh/ctr_drbg.h"
#include "polarsslh/rsa.h"
#include "polarsslh/aes.h"
#include "polarsslh/base64.h"
#include "polarsslh/des.h"
#include "polarsslh/sm2.h"
#include "polarsslh/sha1.h"
#include "log.h"
//#include "polarsslc/SafeKeyboard.cpp"
#define LOGE(tag, fmt, ...) __android_log_print(ANDROID_LOG_ERROR, (tag), (fmt), ## __VA_ARGS__)

/**
 *
 * @param env
 * @param pat
 * @return
 * jString类型转换为const char*类型
 */
char* jstringToChar(JNIEnv* env, jstring jstr) {

    char* rtn = NULL;
    jclass clsstring = env->FindClass("java/lang/String");
    jstring strencode = env->NewStringUTF("GB2312");
    jmethodID mid = env->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B");
    jbyteArray barr = (jbyteArray) env->CallObjectMethod(jstr, mid, strencode);
    jsize alen = env->GetArrayLength(barr);
    jbyte* ba = env->GetByteArrayElements(barr, JNI_FALSE);
    if (alen > 0) {
        rtn = (char*) malloc(alen + 1);
        memcpy(rtn, ba, alen);
        rtn[alen] = 0;
    }
    env->ReleaseByteArrayElements(barr, ba, 0);
    return rtn;
}

/**
 *
 * @param env
 * @param pat
 * @return
 * const char*类型转换为jString类型
 */
jstring char2Jstring( JNIEnv* env, const char* pat )
{
    //定义java String类 strClass
    jclass strClass = (env)->FindClass("java/lang/String");
    //获取java String类方法String(byte[],String)的构造器,用于将本地byte[]数组转换为一个新String
    jmethodID ctorID = (env)->GetMethodID(strClass, "<init>", "([BLjava/lang/String;)V");
    //建立byte数组
    jbyteArray bytes = (env)->NewByteArray((jsize)strlen(pat));
    //将char* 转换为byte数组
    (env)->SetByteArrayRegion(bytes, 0, (jsize)strlen(pat), (jbyte*)pat);
    //设置String, 保存语言类型,用于byte数组转换至String时的参数
    jstring encoding = (env)->NewStringUTF("GB2312");
    //将byte数组转换为java String,并输出
    return (jstring)(env)->NewObject(strClass, ctorID, bytes, encoding);

}


/**
 * Hash类型转换为str
 * @param bin
 * @param lwk
 * @param out
 */
static void _hex_to_str( unsigned char *bin, size_t sm2_len, char *out )
{
    unsigned char c;
    size_t i;

    for( i = 0; i < sm2_len; i++ )
    {
        c = bin[i];
        *out++ =  "0123456789ABCDEF" [c / 16];;
        *out++ =  "0123456789ABCDEF" [c % 16];;
    }
    *out++ = 0x00;
}


/**
 * Aes加解密
 * author lwk
 */
extern "C" {
JNIEXPORT void
JNICALL Java_com_lwk_demo3_MainActivity_Aesencrypt(JNIEnv *env, jobject thiz, jbyteArray jindata, jbyteArray joutdata, jintArray joutLen, jboolean flag) {
    aes_context aes;
    unsigned char* indata = (unsigned char*)env->GetByteArrayElements(jindata, JNI_FALSE);
    int inlen = env->GetArrayLength(jindata);
    unsigned char* outdata = (unsigned char*)env->GetByteArrayElements(joutdata, JNI_FALSE);
    unsigned int* outlen = (unsigned int*)env->GetIntArrayElements(joutLen, JNI_FALSE);
    unsigned char data[4096] = {0};


    if (flag){
        unsigned char tmp[64];
        int keysize = 128;
        memset(tmp, 0, sizeof(tmp));
        strcpy(reinterpret_cast<char *const>(tmp), "1234567890");
        aes_setkey_enc(&aes, tmp, keysize);                         //加密设置密钥

        int result = aes_crypt_cbc(&aes, AES_ENCRYPT, 64, tmp, indata, data);//调用接口对数据indata进行加密   AES_ENCRYPT指定数据进行加密

        if(result != 0 )
        {
            LOGE("提示：","%s, -0x%x","加密失败！", -result);
        }

    }else if (flag == false){

        unsigned char tmp[64];
        int keysize = 128;
        memset(tmp, 0, sizeof(tmp));
        strcpy(reinterpret_cast<char *const>(tmp), "1234567890");
        aes_setkey_dec(&aes, tmp, keysize);                         //解密设置密钥

        int result = aes_crypt_cbc(&aes, AES_DECRYPT, 64, tmp, indata, data);//调用接口对数据indata进行解密   AES_DECRYPT指定数据进行加密

        if(result != 0 )
        {
        LOGE("提示：","%s, -0x%x","解密失败！", -result);
        }
    }
        int datalen = sizeof(data);
//    LOGE("输出长度：","%d",datalen);
        memcpy(outdata, data, datalen);
        *outlen = datalen;

        env->ReleaseByteArrayElements(jindata, (jbyte*)indata, JNI_FALSE);
        env->ReleaseByteArrayElements(joutdata, (jbyte*)outdata, JNI_FALSE);
        env->ReleaseIntArrayElements(joutLen, (jint*)outlen, JNI_FALSE);
    }
}

/**
 * Sm2加解密
 * author lwk
 */
sm2_context sm2_ctx_key;
extern "C" {
JNIEXPORT void
JNICALL Java_com_lwk_demo3_MainActivity_Sm2encrypt(JNIEnv *env, jobject thiz, jbyteArray jindata, jbyteArray joutdata, jintArray joutLen, jboolean flag) {
    unsigned char* indata = (unsigned char*)env->GetByteArrayElements(jindata, JNI_FALSE);
    int inlen = env->GetArrayLength(jindata);
    unsigned char* outdata = (unsigned char*)env->GetByteArrayElements(joutdata, JNI_FALSE);
    unsigned int* outlen = (unsigned int*)env->GetIntArrayElements(joutLen, JNI_FALSE);

    unsigned char data[4096] = {0};
    size_t datalen = 4096;

    if (flag){
        LOGE("KEY","%s","创建密钥");
        sm2_init(&sm2_ctx_key);
        sm2_gen_keypair(&sm2_ctx_key,NULL,NULL);
LOGE("输入数据：","%s",indata);
        PrintHex("INPUT", indata, inlen);
        int sm2_ret = sm2_encrypt(&sm2_ctx_key, (unsigned char *)indata, (size_t)inlen, data, &datalen, NULL, NULL );
        PrintHex("OUTPUT", data, datalen);
        if( sm2_ret != 0 )
        {
            LOGE("提示：","%s, -0x%x","加密失败！", -sm2_ret);
        }
    } else if (flag == false){                                  //SM2解密
        PrintHex("INPUT", indata, inlen);
        int sm2_ret = sm2_decrypt(&sm2_ctx_key, (unsigned char *)indata, (size_t)inlen, data, &datalen);
        PrintHex("OUTPUT", data, datalen);

        if( sm2_ret != 0 )
        {
            LOGE("提示：","%s, -0x%x","解密失败！", -sm2_ret);
        }
    }

    memcpy(outdata, data, datalen);
    *outlen = datalen;

    env->ReleaseByteArrayElements(jindata, (jbyte*)indata, JNI_FALSE);
    env->ReleaseByteArrayElements(joutdata, (jbyte*)outdata, JNI_FALSE);
    env->ReleaseIntArrayElements(joutLen, (jint*)outlen, JNI_FALSE);
}
}


/**
 * Sm2签名及验签
 * author lwk
 */
extern "C" {
JNIEXPORT int
        JNICALL Java_com_lwk_demo3_MainActivity_Sm2sign(JNIEnv *env, jobject thiz, jbyteArray jindata, jbyteArray joutdata, jintArray joutLen) {
unsigned char* indata = (unsigned char*)env->GetByteArrayElements(jindata, JNI_FALSE);
unsigned char* outdata = (unsigned char*)env->GetByteArrayElements(joutdata, JNI_FALSE);
unsigned int* outlen = (unsigned int*)env->GetIntArrayElements(joutLen, JNI_FALSE);
size_t inlen = env->GetArrayLength(jindata);
sm2_context sm2;
sm2_init(&sm2);
sm2_gen_keypair(&sm2,NULL,NULL);
LOGE("Hash之前的indata：","%s", indata);
LOGE("Hash之前前长度：","%d", inlen);

LOGE("输入数据：","%s",indata);
char data[0x400];
unsigned char e[50], r[32], s[32];
char user_id[] = "1234567812345678";
size_t user_id_len = sizeof(indata) - 1;
hash_msg_with_user_id( &sm2, (unsigned char*)indata, inlen,(unsigned char*)user_id, user_id_len,e);

size_t hlen = sizeof(e);

int sm2_ret = sm2_sign(&sm2, e ,hlen, r , s , NULL, NULL);

if( sm2_ret != 0 )
{
LOGE("提示：","%s, -0x%x","签名失败！", -sm2_ret);
}else if(sm2_ret == 0){
LOGE("提示：","%s, -0x%x","签名成功！", -sm2_ret);
}

_hex_to_str( r, 0x20, data );
_hex_to_str( s, 0x20, data );

sm2_ret = sm2_verify(&sm2, e, hlen, r, s);

if( sm2_ret != 0 )
{
LOGE("提示：","%s, -0x%x","验签失败！", -sm2_ret);
}

memcpy(outdata, data, sizeof(data));
*outlen = sizeof(data);

env->ReleaseByteArrayElements(jindata, (jbyte*)indata, JNI_FALSE);
env->ReleaseByteArrayElements(joutdata, (jbyte*)outdata, JNI_FALSE);
env->ReleaseIntArrayElements(joutLen, (jint*)outlen, JNI_FALSE);
return sm2_ret;
}
}

/**
 * Des加解密
 * author lwk
 */
des_context des;
extern "C" {
JNIEXPORT void
        JNICALL Java_com_lwk_demo3_MainActivity_Desencrypt(JNIEnv *env, jobject thiz, jbyteArray jindata, jbyteArray joutdata, jintArray joutLen, jboolean flag) {
        unsigned char* indata = (unsigned char*)env->GetByteArrayElements(jindata, JNI_FALSE);
        int inlen = env->GetArrayLength(jindata);
        unsigned char* outdata = (unsigned char*)env->GetByteArrayElements(joutdata, JNI_FALSE);
        unsigned int* outlen = (unsigned int*)env->GetIntArrayElements(joutLen, JNI_FALSE);

        unsigned char data[4096] = {0};
        size_t datalen = 4096;
        unsigned char key[64];
        int keysize = 128;
        memset(key, 0, sizeof(key));
        strcpy(reinterpret_cast<char *const>(key), "12345678");

        if (flag){
        LOGE("KEY","%s","创建密钥");
        des_init(&des);
        des_setkey_enc(&des,key);
        LOGE("输入数据：","%s",indata);
        int des_ret = des_crypt_cbc(&des, DES_ENCRYPT,64, key, indata,data );
        LOGE("输出数据：","%s",data);
        if( des_ret != 0 )
            {
                LOGE("提示：","%s, -0x%x","加密失败！", -des_ret);
            }
        } else if (flag == false){                                  //DES解密
        des_setkey_dec(&des,key);
        LOGE("输入数据：","%s",indata);
        int des_ret = des_crypt_cbc(&des,DES_DECRYPT,64, key, indata,data );
        LOGE("输出数据：","%s",data);
        if( des_ret != 0 )
            {
                LOGE("提示：","%s, -0x%x","解密失败！", -des_ret);
            }
}

memcpy(outdata, data, datalen);
*outlen = datalen;

env->ReleaseByteArrayElements(jindata, (jbyte*)indata, JNI_FALSE);
env->ReleaseByteArrayElements(joutdata, (jbyte*)outdata, JNI_FALSE);
env->ReleaseIntArrayElements(joutLen, (jint*)outlen, JNI_FALSE);
}
}

/**
 * Des3加解密
 * author lwk
 */
des3_context des3;
extern "C" {
JNIEXPORT void
        JNICALL Java_com_lwk_demo3_MainActivity_Des3encrypt(JNIEnv *env, jobject thiz, jbyteArray jindata, jbyteArray joutdata, jintArray joutLen, jboolean flag) {
        unsigned char* indata = (unsigned char*)env->GetByteArrayElements(jindata, JNI_FALSE);
        int inlen = env->GetArrayLength(jindata);
        unsigned char* outdata = (unsigned char*)env->GetByteArrayElements(joutdata, JNI_FALSE);
        unsigned int* outlen = (unsigned int*)env->GetIntArrayElements(joutLen, JNI_FALSE);

        unsigned char data[4096] = {0};
        size_t datalen = 4096;
        unsigned char key[64];
        int keysize = DES_KEY_SIZE*3;
        memset(key, 0, sizeof(key));
        strcpy(reinterpret_cast<char *const>(key), "123456781234567812345678");

        if (flag){
        LOGE("KEY","%s","创建密钥");
        des3_init(&des3);
        des3_set3key_enc(&des3,key);
        LOGE("输入数据：","%s",indata);
        int des3_ret = des3_crypt_cbc(&des3, DES_ENCRYPT,64, key, indata,data );
        LOGE("输出数据：","%s",data);
        if( des3_ret != 0 )
        {
        LOGE("提示：","%s, -0x%x","加密失败！", -des3_ret);
        }
        } else if (flag == false){                                  //DES解密
        des3_set3key_dec(&des3,key);
        LOGE("输入数据：","%s",indata);
        int des3_ret = des3_crypt_cbc(&des3,DES_DECRYPT,64, key, indata,data );
        LOGE("输出数据：","%s",data);
        if( des3_ret != 0 )
            {
            LOGE("提示：","%s, -0x%x","解密失败！", -des3_ret);
            }
        }

            memcpy(outdata, data, datalen);
            *outlen = datalen;

            env->ReleaseByteArrayElements(jindata, (jbyte*)indata, JNI_FALSE);
            env->ReleaseByteArrayElements(joutdata, (jbyte*)outdata, JNI_FALSE);
            env->ReleaseIntArrayElements(joutLen, (jint*)outlen, JNI_FALSE);
        }
}


/**
 * Rsa加解密
 * author lwk
 */

const unsigned int RSA_KEY_SIZE = 1024;        // RSA 公钥的位数
const unsigned int AES_KEY_SIZE = 256;
const unsigned int EXPONENT = 65537;
const unsigned int BUFFER_SIZE = 1024;
class rsa
{
public:
    rsa()
    {
        memset(rsa_n, 0, BUFFER_SIZE);
        memset(rsa_e, 0, BUFFER_SIZE);
        memset(rsa_d, 0, BUFFER_SIZE);
        memset(rsa_p, 0, BUFFER_SIZE);
        memset(rsa_q, 0, BUFFER_SIZE);
        memset(rsa_dp, 0, BUFFER_SIZE);
        memset(rsa_dq, 0, BUFFER_SIZE);
        memset(rsa_qp, 0, BUFFER_SIZE);
        n_len = BUFFER_SIZE;
        e_len = BUFFER_SIZE;
        d_len = BUFFER_SIZE;
        p_len = BUFFER_SIZE;
        q_len = BUFFER_SIZE;
        dp_len = BUFFER_SIZE;
        dq_len = BUFFER_SIZE;
        qp_len = BUFFER_SIZE;
    }

    unsigned char    rsa_n[BUFFER_SIZE];
    unsigned char    rsa_e[BUFFER_SIZE];
    unsigned char    rsa_d[BUFFER_SIZE];
    unsigned char    rsa_p[BUFFER_SIZE];
    unsigned char    rsa_q[BUFFER_SIZE];
    unsigned char    rsa_dp[BUFFER_SIZE];
    unsigned char    rsa_dq[BUFFER_SIZE];
    unsigned char    rsa_qp[BUFFER_SIZE];

    unsigned int n_len;
    unsigned int e_len;
    unsigned int d_len;
    unsigned int p_len;
    unsigned int q_len;
    unsigned int dp_len;
    unsigned int dq_len;
    unsigned int qp_len;
};

void generate_rsa(rsa& r)
{
    // 生成RSA密钥对
    rsa_context    rsa;
    entropy_context    entropy;
    ctr_drbg_context    ctr_drbg;

    entropy_init(&entropy);

    assert(ctr_drbg_init(&ctr_drbg, entropy_func, &entropy, nullptr, 0) == 0);

    rsa_init(&rsa, RSA_PKCS_V15, 0);

    assert(rsa_gen_key(&rsa, ctr_drbg_random, &ctr_drbg, RSA_KEY_SIZE, EXPONENT) == 0);

    assert(mpi_write_binary(&rsa.N, r.rsa_n, BUFFER_SIZE) == 0);
    assert(mpi_write_binary(&rsa.E, r.rsa_e, BUFFER_SIZE) == 0);
    assert(mpi_write_binary(&rsa.D, r.rsa_d, BUFFER_SIZE) == 0);
    assert(mpi_write_binary(&rsa.P, r.rsa_p, BUFFER_SIZE) == 0);
    assert(mpi_write_binary(&rsa.Q, r.rsa_q, BUFFER_SIZE) == 0);
    assert(mpi_write_binary(&rsa.DP, r.rsa_dp, BUFFER_SIZE) == 0);
    assert(mpi_write_binary(&rsa.DQ, r.rsa_dq, BUFFER_SIZE) == 0);
    assert(mpi_write_binary(&rsa.QP, r.rsa_qp, BUFFER_SIZE) == 0);

    //写入文件保存,每个间隔1024字节
//    FILE * fp = fopen("rsa","wb");
    FILE * fp = fopen("/sdcard/rsa","w");
    fwrite(r.rsa_n,BUFFER_SIZE,1,fp);
    fwrite(r.rsa_e,BUFFER_SIZE,1,fp);
    fwrite(r.rsa_d,BUFFER_SIZE,1,fp);
    fwrite(r.rsa_p,BUFFER_SIZE,1,fp);
    fwrite(r.rsa_q,BUFFER_SIZE,1,fp);
    fwrite(r.rsa_dp,BUFFER_SIZE,1,fp);
    fwrite(r.rsa_dq,BUFFER_SIZE,1,fp);
    fwrite(r.rsa_qp,BUFFER_SIZE,1,fp);
    fclose(fp);
}

void read_rsa(rsa& r)
{
    //读取保存的RSA相关信息
    FILE * fp = fopen("rsa","rb");
    fread(r.rsa_n,BUFFER_SIZE,1,fp);
    fread(r.rsa_e,BUFFER_SIZE,1,fp);
    fread(r.rsa_d,BUFFER_SIZE,1,fp);
    fread(r.rsa_p,BUFFER_SIZE,1,fp);
    fread(r.rsa_q,BUFFER_SIZE,1,fp);
    fread(r.rsa_dp,BUFFER_SIZE,1,fp);
    fread(r.rsa_dq,BUFFER_SIZE,1,fp);
    fread(r.rsa_qp,BUFFER_SIZE,1,fp);
    fclose(fp);
}

// 加密
void encrypt(
        const rsa &r,
        const unsigned char* plaintext,
        unsigned int plaintext_size,
        unsigned char *ciphertext,
        unsigned int *ciphertext_size)
{
    rsa_context            rsa;
    entropy_context        entropy;
    ctr_drbg_context    ctr_drbg;

    entropy_init(&entropy);
    assert(ctr_drbg_init(&ctr_drbg, entropy_func, &entropy, nullptr, 0) == 0);

    rsa_init(&rsa, RSA_PKCS_V15, 0);

    assert(mpi_read_binary(&rsa.N, r.rsa_n, BUFFER_SIZE) == 0);
    assert(mpi_read_binary(&rsa.E, r.rsa_e, BUFFER_SIZE) == 0);

    *ciphertext_size = rsa.len = (mpi_msb(&rsa.N) + 7) >> 3;

    int s = rsa_pkcs1_encrypt(&rsa, ctr_drbg_random, &ctr_drbg, RSA_PUBLIC, plaintext_size, (const unsigned char*)plaintext, ciphertext);
    if( s != 0 )
    {
        LOGE("提示：","%s, -0x%x","解密失败！", -s);
    }
}

// 解密
void decrypt(
        const rsa &r,
        const unsigned char* ciphertext,
        unsigned int ciphertext_size,
        unsigned char *plaintext,
        size_t &plaintext_size)
{
    rsa_context            rsa;
    entropy_context        entropy;
    ctr_drbg_context    ctr_drbg;

    entropy_init(&entropy);
    assert(ctr_drbg_init(&ctr_drbg, entropy_func, &entropy, nullptr, 0) == 0);

    rsa_init(&rsa, RSA_PKCS_V15, 0);

    assert(mpi_read_binary(&rsa.N, r.rsa_n, BUFFER_SIZE) == 0);
    assert(mpi_read_binary(&rsa.E, r.rsa_e, BUFFER_SIZE) == 0);
    assert(mpi_read_binary(&rsa.D, r.rsa_d, BUFFER_SIZE) == 0);
    assert(mpi_read_binary(&rsa.P, r.rsa_p, BUFFER_SIZE) == 0);
    assert(mpi_read_binary(&rsa.Q, r.rsa_q, BUFFER_SIZE) == 0);
    assert(mpi_read_binary(&rsa.DP, r.rsa_dp, BUFFER_SIZE) == 0);
    assert(mpi_read_binary(&rsa.DQ, r.rsa_dq, BUFFER_SIZE) == 0);
    assert(mpi_read_binary(&rsa.QP, r.rsa_qp, BUFFER_SIZE) == 0);

    rsa.len = (mpi_msb(&rsa.N) + 7) >> 3;

    int s = rsa_pkcs1_decrypt(&rsa, 0, &ctr_drbg, RSA_PRIVATE, &plaintext_size, ciphertext, plaintext, plaintext_size);
    if( s != 0 )
    {
        LOGE("提示：","%s, -0x%x","解密失败！", -s);
    }
}


// 签名
void rsa_sign(
        const rsa &r,
        const unsigned char* plaintext,
        unsigned int plaintext_size,
        unsigned char *ciphertext,
        unsigned int *ciphertext_size)
{
    rsa_context            rsa;
    entropy_context        entropy;
    ctr_drbg_context    ctr_drbg;
    unsigned char sha1sum[20];
    int PT_LEN = 0;
    sha1(plaintext,PT_LEN,sha1sum);
//    LOGE("Hash之后的indata：","%s", sha1sum);
//    LOGE("Hash之后的长度：","%d", PT_LEN);
    entropy_init(&entropy);
    assert(ctr_drbg_init(&ctr_drbg, entropy_func, &entropy, nullptr, 0) == 0);

    rsa_init(&rsa, RSA_PKCS_V15, 0);

    assert(mpi_read_binary(&rsa.N, r.rsa_n, BUFFER_SIZE) == 0);
    assert(mpi_read_binary(&rsa.E, r.rsa_e, BUFFER_SIZE) == 0);
    assert(mpi_read_binary(&rsa.D, r.rsa_d, BUFFER_SIZE) == 0);
    assert(mpi_read_binary(&rsa.P, r.rsa_p, BUFFER_SIZE) == 0);
    assert(mpi_read_binary(&rsa.Q, r.rsa_q, BUFFER_SIZE) == 0);
    assert(mpi_read_binary(&rsa.DP, r.rsa_dp, BUFFER_SIZE) == 0);
    assert(mpi_read_binary(&rsa.DQ, r.rsa_dq, BUFFER_SIZE) == 0);
    assert(mpi_read_binary(&rsa.QP, r.rsa_qp, BUFFER_SIZE) == 0);

    rsa.len = (mpi_msb(&rsa.N) + 7) >> 3;

    int s = rsa_pkcs1_sign(&rsa, ctr_drbg_random, &ctr_drbg, RSA_PRIVATE, POLARSSL_MD_SHA1 , PT_LEN, (const unsigned char*)sha1sum, ciphertext);

    if( s != 0 )
    {
        LOGE("提示：","%s, -0x%x","验证失败！", -s);
    }
}

// 验签
int rsa_verify(
        const rsa &r,
        const unsigned char* plaintext,
        unsigned int plaintext_size,
        unsigned char *ciphertext,
        unsigned int *ciphertext_size)
{
    unsigned char sha1sum[20];
    int PT_LEN = 0;
    rsa_context            rsa;
    entropy_context        entropy;
    ctr_drbg_context    ctr_drbg;
    sha1(plaintext,PT_LEN,sha1sum);
    entropy_init(&entropy);
    assert(ctr_drbg_init(&ctr_drbg, entropy_func, &entropy, nullptr, 0) == 0);

    rsa_init(&rsa, RSA_PKCS_V15, 0);

    assert(mpi_read_binary(&rsa.N, r.rsa_n, BUFFER_SIZE) == 0);
    assert(mpi_read_binary(&rsa.E, r.rsa_e, BUFFER_SIZE) == 0);

    *ciphertext_size = rsa.len = (mpi_msb(&rsa.N) + 7) >> 3;

    int s = rsa_pkcs1_verify(&rsa, ctr_drbg_random, &ctr_drbg, RSA_PUBLIC, POLARSSL_MD_SHA1 , PT_LEN, (const unsigned char*)sha1sum, ciphertext);

    if( s != 0 )
    {
        LOGE("提示：","%s, -0x%x","验签失败！", -s);
        return 1;
    }else if (s == 0){
        LOGE("提示成功：","%d", s);
        return 0;
    }
}


/**
 * Rsa加解密
 * author lwk
 */
rsa    r;
extern "C" {
JNIEXPORT void
        JNICALL Java_com_lwk_demo3_MainActivity_Rsaencrypt(JNIEnv *env, jobject thiz, jbyteArray jindata, jbyteArray joutdata, jintArray joutLen, jboolean flag) {
unsigned char* indata = (unsigned char*)env->GetByteArrayElements(jindata, JNI_FALSE);
int inlen = env->GetArrayLength(jindata);
unsigned char* outdata = (unsigned char*)env->GetByteArrayElements(joutdata, JNI_FALSE);
unsigned int* outlen = (unsigned int*)env->GetIntArrayElements(joutLen, JNI_FALSE);

unsigned char data[BUFFER_SIZE] = {0};
unsigned int datalen = BUFFER_SIZE;
if(flag) {
generate_rsa(r);                                                //生成密钥
encrypt(r, indata, sizeof(indata), data, &datalen);             //RSA加密函数
//            LOGE("输出加密后：", "%s", data) ;
//            LOGE("输出加密后长度：", "%d", datalen) ;
}else if(!flag){
//            LOGE("解密输出：", "%s", indata);
//            LOGE("解密输出长度：", "%d", inlen);
size_t dstlen = 0;
base64_encode(NULL,&dstlen,indata,inlen);//第一次获取加密后的目标长度
unsigned char* dstbuf = new unsigned char[dstlen+1];
memset(dstbuf,0,dstlen+1);
base64_encode(dstbuf,&dstlen,indata,inlen);//转换为BASE64编码
printf("%s\n",dstbuf);
size_t    output_len = BUFFER_SIZE;
dstlen = 0;
base64_decode(NULL,&dstlen,dstbuf,strlen((const char*)dstbuf));
unsigned char* srcbuf = new unsigned char[dstlen];
base64_decode(srcbuf,&dstlen,dstbuf,strlen((const char*)dstbuf));
decrypt(r, srcbuf, dstlen, data, output_len);                       //RSA解密函数
datalen = output_len;
printf("%s\n",data);
system("pause");
LOGE("输出解密后：","%s",data);
}
memcpy(outdata, data, datalen);
*outlen = datalen;
env->ReleaseByteArrayElements(jindata, (jbyte*)indata, JNI_FALSE);
env->ReleaseByteArrayElements(joutdata, (jbyte*)outdata, JNI_FALSE);
env->ReleaseIntArrayElements(joutLen, (jint*)outlen, JNI_FALSE);
}
}

/**
 * Rsa签名及验签
 * author lwk
 */
size_t len;
rsa_context rsa;
extern "C" {
JNIEXPORT int
        JNICALL Java_com_lwk_demo3_MainActivity_RsaSign(JNIEnv *env, jobject thiz, jbyteArray jindata, jbyteArray joutdata, jintArray joutLen) {
unsigned char* indata = (unsigned char*)env->GetByteArrayElements(jindata, JNI_FALSE);
int inlen = env->GetArrayLength(jindata);
unsigned char* outdata = (unsigned char*)env->GetByteArrayElements(joutdata, JNI_FALSE);
unsigned int* outlen = (unsigned int*)env->GetIntArrayElements(joutLen, JNI_FALSE);

unsigned char data[BUFFER_SIZE] = {0};
unsigned int datalen = BUFFER_SIZE;

generate_rsa(r);                                                //生成密钥
//LOGE("输出签名：", "%s", "未开始签名") ;
rsa_sign(r, indata, sizeof ( indata ) , data , & datalen ) ;             //RSA加密函数
//LOGE("输出签名：", "%s", data) ;
//LOGE("输出原文：", "%s", indata) ;
//LOGE("输出签名后长度：", "%d", datalen) ;
int s = rsa_verify(r, indata, sizeof ( indata ) , data , & datalen ) ;
//LOGE("输出原文：", "%s", indata) ;

memcpy(outdata, data, datalen);
*outlen = datalen;
env->ReleaseByteArrayElements(jindata, (jbyte*)indata, JNI_FALSE);
env->ReleaseByteArrayElements(joutdata, (jbyte*)outdata, JNI_FALSE);
env->ReleaseIntArrayElements(joutLen, (jint*)outlen, JNI_FALSE);
return s ;
}
}
